/*******************************************************
 **
 ** Provided by ���ɽ�, Fuzhou University
 ** Email: mileden@126.com
 ** Homepage: http://sonew.512j.com/
 ** This product is free for use.
 ** last changed 2009-2-14
 ** 使用他人模板--参考xvid api 手册
 *******************************************************/

#include <cstring>
#include "xvidcodec.h"
#include <xvid.h>
//设置解码高宽比
XvidCodec::XvidCodec(int w, int h)
{
    width = w;
    height = h;
    encoderAvailable = false;
    enc_handle = 0;

    if ( enc_init() == 0 )
        encoderAvailable = true;
}

XvidCodec::~XvidCodec()
{
    enc_stop();
    encoderAvailable = false;
}

int XvidCodec::enc_init()
{
    xvid_gbl_init_t xvid_gbl_init;
    xvid_enc_create_t xvid_enc_create;
    int xerr;

    /*------------------------------------------------------------------------
     * XviD core initialization
     *----------------------------------------------------------------------*/

    /* Set version -- version checking will done by xvidcore */
    memset( &xvid_gbl_init, 0, sizeof( xvid_gbl_init ) );
    xvid_gbl_init.version = XVID_VERSION;

    /* Initialize XviD core -- Should be done once per __process__ */
    xvid_global( 0, XVID_GBL_INIT, &xvid_gbl_init, 0 );

    /*------------------------------------------------------------------------
     * XviD encoder initialization
     *----------------------------------------------------------------------*/

    /* Version again */
    memset(&xvid_enc_create, 0, sizeof(xvid_enc_create));
    xvid_enc_create.version = XVID_VERSION;

    /* Width and Height of input frames */
    xvid_enc_create.width = width;
    xvid_enc_create.height = height;
    xvid_enc_create.profile = XVID_PROFILE_AS_L3;

    /* Frame rate - Do some quick float fps = fincr/fbase hack */
    xvid_enc_create.fincr = 1;
    xvid_enc_create.fbase =  FPS;

    /* I use a small value here, since will not encode whole movies, but short clips */
    xerr = xvid_encore( 0, XVID_ENC_CREATE, &xvid_enc_create, 0 );

    /* Retrieve the encoder instance from the structure */
    enc_handle = xvid_enc_create.handle;

    return xerr;
}

int XvidCodec::enc_stop()
{
    int xerr;

    /* Destroy the encoder instance */
    xerr = xvid_encore(enc_handle, XVID_ENC_DESTROY, 0, 0);

    return xerr;
}

int XvidCodec::encode(unsigned char* image, unsigned char* bitstream)
{
    int ret;
    xvid_enc_frame_t xvid_enc_frame;
    xvid_enc_stats_t xvid_enc_stats;

    /* Version for the frame and the stats */
    memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame));
    xvid_enc_frame.version = XVID_VERSION;

    memset(&xvid_enc_stats, 0, sizeof(xvid_enc_stats));
    xvid_enc_stats.version = XVID_VERSION;

    /* Bind output buffer */
    xvid_enc_frame.bitstream = bitstream;
    xvid_enc_frame.length = -1;

    /* Initialize input image fields */
    if (image) {
        xvid_enc_frame.input.plane[0] = image;
        xvid_enc_frame.input.csp = XVID_CSP_RGB;
        xvid_enc_frame.input.stride[0] = width*3;
    } else {
        xvid_enc_frame.input.csp = 0;
    }

    /* Set up core's general features */
	xvid_enc_frame.vol_flags = 0;

    /* Set up core's general features */
    xvid_enc_frame.vop_flags = 0;

    /* Frame type */
    /* Sometimes we might want to force the last frame to be a P Frame */
    xvid_enc_frame.type = XVID_TYPE_AUTO;

    /* Force the right quantizer -- It is internally managed by RC plugins */
    xvid_enc_frame.quant = 0;

     /* Set up motion estimation flags */
     xvid_enc_frame.motion = 0;

    /* Encode the frame */
    ret = xvid_encore(enc_handle, XVID_ENC_ENCODE, &xvid_enc_frame,
                      &xvid_enc_stats);

    return ret;
}

